/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.gov.cemaden.imagefilter.watcher;

import br.gov.cemaden.imagefilter.concurrent.FilterCallable;
import br.gov.cemaden.imagefilter.repository.XMLRepositoryReader;
import br.gov.cemaden.imagefilter.repository.RepositoryReader;
import br.gov.cemaden.watcher.FileWatcherRepeat;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
import org.apache.log4j.Logger;

/**
 *
 * @author Jether
 * @author Alan
 */
public class ImageAPIWatcher extends FileWatcherRepeat {

    private String pathSource, pathTarget;
    private int option;
    private Properties properties;
    private Map<String, String> values;
    ExecutorService executorPool;
    Collection<FilterCallable> threads;
    
    private static Logger logger = Logger.getLogger(ImageAPIWatcher.class);

    /**
     * 
     * @param source
     * @param target
     * @param option
     * @param recursive
     * @param procExistents
     * @param properties 
     */
    public ImageAPIWatcher(String source, String target, int option, boolean recursive, boolean procExistents, Properties properties) {
        
        super(source, recursive, procExistents);
        
        this.pathTarget = target;
        this.pathSource = source;       
        this.option = option;
        this.properties = properties;
        
        String repository = properties.getProperty("repository.filepath", "repository.xml");
        repository  =(repository.isEmpty()) ? "repository.xml" : repository;
        RepositoryReader reader = new XMLRepositoryReader(repository);
        values = reader.getElements();
        
        if( values.isEmpty() ){
            throw new RuntimeException("Values are empty!");
        }        
        
        executorPool = new ThreadPoolExecutor(8, 10, 10, 
                TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(values.size()), 
                Executors.defaultThreadFactory());        
        
        threads = new ArrayList<FilterCallable>();
    }        

    @Override
    public boolean handleCreate(Path path) {
        return handleModify(path);
    }

    @Override
    public boolean handleModify(Path path) {        
        
        String filename = path.getFileName().toString();
        
        for (Map.Entry<String, String> entry : values.entrySet()) {
            
            if( filename.matches( "^" + entry.getValue() + ".*" ) ){                
                
                // Uses Callable interface and return the result expected, in this case, a Boolean
                try{
                    return executorPool.submit(new FilterCallable(path.toString(), pathTarget, entry.getKey(), option)).get();
                }
                catch(ExecutionException e){
                    logger.error("Error when executing the filter: " + e.getMessage());
                    logger.error(e);
                }
                catch(InterruptedException e){
                    logger.error("The filter thread was interrupted: " + e.getMessage());
                    logger.error(e);
                }
            }
        }                       
        
        return false;
    }    
}
